/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.max.cjs.bean;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.Part;
import org.max.cjs.model.Schedule;
import org.max.cjs.model.TemplateDescription;
import org.max.cjs.model.ext.SystemUser;
import org.max.cjs.service.interfac.IScheduleService;
import org.max.cjs.service.interfac.ISystemUserService;
import org.max.cjs.service.interfac.ITemplateDescriptionService;
import org.max.cjs.util.Clazz;
import org.max.cjs.util.FacesUtil;
import org.omnifaces.util.Faces;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.LazyScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;

/**
 *
 * @author user
 */
@ManagedBean
@SessionScoped
public class ScheduleBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private ScheduleModel lazyEventModel;
    private ScheduleEvent event = new DefaultScheduleEvent();
    private Schedule schedule = new Schedule();
    private List<String> listMonth;
    private Part file;
    String userName;
    String password;
    //private String linkShare = "if (navigator.userAgent.toLowerCase().indexOf('opera') != 1 & amp; & amp; window.event.preventDefault) window.event.preventDefault(); this.newWindow = window.open( & #039; http://www.cjavaperu.com/informe/client.php?locale = es & amp; url = & #039; + escape(document.location.href) + & #039; & amp; referrer = & #039; + escape(document.referrer), 'mibew', 'toolbar=0,scrollbars=0,location=0,status=1,menubar=0,width=640,height=480,resizable=1'); this.newWindow.focus(); this.newWindow.opener = window; return false;";
    private String linkShare = "if(navigator.userAgent.toLowerCase().indexOf('opera') != -1 &amp;&amp; window.event.preventDefault) window.event.preventDefault();this.newWindow = window.open('http://www.cjavaperu.com/informe/client.php?locale=es&amp;url='+escape(document.location.href)+'&amp;referrer='+escape(document.referrer), 'mibew', 'toolbar=0,scrollbars=0,location=0,status=1,menubar=0,width=640,height=480,resizable=1');this.newWindow.focus();this.newWindow.opener=window;return false;";
    private Integer htmlDescriptId;

    private TemplateDescription templateDescription = new TemplateDescription();
    private List<TemplateDescription> listTemplate;
    private String mothSelected;

    @ManagedProperty("#{scheduleService}")
    IScheduleService scheduleService;
    @ManagedProperty("#{systemUserService}")
    ISystemUserService systemUserService;
    @ManagedProperty("#{templateDescriptionService}")
    ITemplateDescriptionService templateDescriptionService;

    private String image = null;

    public void logIn() throws IOException, Exception {
        List<SystemUser> list = systemUserService.getByCredential(userName, password);
        if (list.isEmpty()) {
            FacesUtil.addMessage("Credenciales no válidas", "Usuario o contraseña inválida", FacesMessage.SEVERITY_ERROR);
        } else {
            Faces.setSessionAttribute(FacesUtil.ATTRIBUTE_USER, "CJava Perú");
            Faces.redirect("loged.jsf");
        }
    }

    public void removeSchedule() throws Exception {
        if (schedule.getId() != null) {
            scheduleService.delete(schedule);
            FacesUtil.addMessage("Eliminado", null, FacesMessage.SEVERITY_WARN);
            schedule = new Schedule();
        }
    }

    public void removeTemplate(TemplateDescription temp) throws Exception {
        if (temp.getId() != null) {
            templateDescriptionService.delete(temp);
            FacesUtil.addMessage("Plantilla Eliminada", null, FacesMessage.SEVERITY_WARN);
            clearTemplateDescription();
            clearValues();
        }

    }

    public void replicateSchedule() throws Exception {
        if (schedule.getDayActive() == null || schedule.getDescriptionHtml() == null
                || schedule.getState() == null || schedule.getType() == null) {

        } else {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            List<Integer> listScheTemp = scheduleService.listHQL("select s.id as id from Schedule s where s.name='(name)' and s.dayActive='(day)'"
                    .replace("(name)", schedule.getName())
                    .replace("(day)", dateFormat.format(schedule.getDayActive()) + ""));
            if (listScheTemp.isEmpty()) {
                System.out.println("Entrando...");
                schedule.setId(null);
                scheduleService.save(schedule);
                schedule = new Schedule();
                FacesUtil.addMessage("Calendario Actualizado...", null, FacesMessage.SEVERITY_INFO);
                htmlDescriptId = 0;
            } else {
                FacesUtil.addMessage("Error: ", "No puede haber el mismo nombre en la misma fecha.", FacesMessage.SEVERITY_ERROR);
                FacesUtil.addMessage("Solución: ", "Cambie o ponga otro nombre.", FacesMessage.SEVERITY_WARN);
            }
        }
    }

    public void saveOrUpdateSchedule() throws Exception {
        if (schedule.getDayActive() == null || schedule.getDescriptionHtml() == null
                || schedule.getState() == null || schedule.getType() == null) {

        } else {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            if (schedule.getId() == null) {

                List<Schedule> listScheTemp = scheduleService.listHQL("from Schedule s where s.name='(name)' and s.dayActive='(day)'"
                        .replace("(name)", schedule.getName())
                        .replace("(day)", dateFormat.format(schedule.getDayActive()) + ""));
                if (listScheTemp.isEmpty()) {
                    System.out.println("Entrando...");
                    scheduleService.save(schedule);
                    schedule = new Schedule();
                    FacesUtil.addMessage("Calendario Actualizado...", null, FacesMessage.SEVERITY_INFO);
                    htmlDescriptId = 0;
                } else {
                    FacesUtil.addMessage("Error: ", "No puede haber el mismo nombre en la misma fecha.", FacesMessage.SEVERITY_ERROR);
                    FacesUtil.addMessage("Solución: ", "Cambie o ponga otro nombre.", FacesMessage.SEVERITY_WARN);
                }
            } else {
                List<Schedule> listScheTemp = scheduleService.listHQL("from Schedule s where s.name='(name)' and s.dayActive='(day)'"
                        .replace("(name)", schedule.getName())
                        .replace("(day)", dateFormat.format(schedule.getDayActive()) + ""));
                if (listScheTemp.isEmpty()) {
                    scheduleService.update(schedule);
                    schedule = new Schedule();
                    htmlDescriptId = 0;
                    FacesUtil.addMessage("Calendario Actualizado...", null, FacesMessage.SEVERITY_INFO);
                } else {
                    boolean firstUpdate = true;
                    for (Schedule scT : listScheTemp) {
                        if (scT.getName().equals(schedule.getName())) {
                            firstUpdate = false;
                        }
                    }
                    if (firstUpdate) {// AL ACTUALIZAR LOS NOMBRES SON DISTINTOS, NO IMPORTA EN ID
                        scheduleService.update(schedule);
                        schedule = new Schedule();
                        htmlDescriptId = 0;
                        FacesUtil.addMessage("Calendario Actualizado...", null, FacesMessage.SEVERITY_INFO);
                    } else { //ENCONTRO UN NOMBRE IGUAL
                        firstUpdate = false;
                        for (Schedule scT : listScheTemp) {
                            if (scT.getName().equals(schedule.getName()) && scT.getId().equals(schedule.getId())) {
                                firstUpdate = true;
                                break;
                            }
                        }
                        if (firstUpdate) { //ESTA ACTUALIZANDO SOLO EL CONTENIDO DE LA MISMA SELECCIONADA
                            scheduleService.update(schedule);
                            schedule = new Schedule();
                            htmlDescriptId = 0;
                            FacesUtil.addMessage("Calendario Actualizado...", null, FacesMessage.SEVERITY_INFO);
                        } else { //
                            FacesUtil.addMessage("Error: ", "No puede haber el mismo nombre en la misma fecha.", FacesMessage.SEVERITY_ERROR);
                            FacesUtil.addMessage("Solución: ", "Cambie o ponga otro nombre.", FacesMessage.SEVERITY_WARN);
                        }
                    }
                }

            }
        }

    }

    public void clearValues() {
        schedule = new Schedule();
        htmlDescriptId = 0;
    }

    public void clearTemplateDescription() {
        templateDescription = new TemplateDescription();
    }

    public void updateViewHTML() {
        if (htmlDescriptId.equals(0)) {
            schedule.setDescriptionHtml("");
        } else {
            for (int i = 0; i < listTemplate.size(); i++) {
                if (listTemplate.get(i).getId().equals(htmlDescriptId)) {
                    schedule.setDescriptionHtml(listTemplate.get(i).getDescHtml());
                    break;
                }
            }
        }

    }

    public void saveOrUpdateTemplate() throws Exception {
        if (templateDescription.getId() == null) {
            templateDescriptionService.save(templateDescription);
            FacesUtil.addMessage("Guardado con éxito", null, FacesMessage.SEVERITY_INFO);
            listTemplate = null;
            String content = templateDescription.getDescHtml();
            templateDescription = new TemplateDescription();
            templateDescription.setDescHtml(content);
        } else {
            templateDescriptionService.update(templateDescription);
            FacesUtil.addMessage("Actualizado con éxito", null, FacesMessage.SEVERITY_INFO);
            listMonth = null;
            String content = templateDescription.getDescHtml();
            templateDescription = new TemplateDescription();
            templateDescription.setDescHtml(content);
        }
    }

    public ScheduleModel getLazyEventModel() {

        if (lazyEventModel == null) {
            lazyEventModel = new LazyScheduleModel() {
                @Override
                public void loadEvents(Date start, Date end) {
                    try {
                        String hql = "select s.id as id, s.name as name, s.state as state, s.dayActive as dayActive, s.type as type from Schedule s where"
                                + " s.dayActive BETWEEN :start and :end";
                        List<Date> listParam = new ArrayList<>();
                        listParam.add(start);
                        listParam.add(end);
                        List<Schedule> list = scheduleService.listHQL(hql, 1, listParam);
                        DefaultScheduleEvent d;
                        for (Schedule schedule : list) {
                            if (schedule.getState() != null && schedule.getState().equals(Clazz.STATE.INACTIVO)) {
                                addEvent(new DefaultScheduleEvent(schedule.getName(), schedule.getDayActive(), schedule.getDayActive(), "public-event-desabilitado"));
                            } else if (schedule.getType() != null && schedule.getType().equals(Clazz.TYPE.EVENTO)) {
                                addEvent(new DefaultScheduleEvent(schedule.getName(), schedule.getDayActive(), schedule.getDayActive(), "public-event-evento"));
                            } else if (schedule.getType() != null && schedule.getType().equals(Clazz.TYPE.INICIO_CURSO)) {
                                addEvent(new DefaultScheduleEvent(schedule.getName(), schedule.getDayActive(), schedule.getDayActive(), "public-event-curso"));
                            } else if (schedule.getType() != null && schedule.getType().equals(Clazz.TYPE.SORTEO)) {
                                addEvent(new DefaultScheduleEvent(schedule.getName(), schedule.getDayActive(), schedule.getDayActive(), "public-event-sorteo"));
                            } else {
                                addEvent(new DefaultScheduleEvent(schedule.getName(), schedule.getDayActive(), schedule.getDayActive()));
                            }

                        }

                    } catch (Exception ex) {
                        Logger.getLogger(ScheduleBean.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            };
        }
        return lazyEventModel;
    }

    public void onEventSelect(SelectEvent selectEvent) throws Exception {
        ScheduleEvent eventTemp = (ScheduleEvent) selectEvent.getObject();
        schedule = scheduleService.getByHQL("from Schedule s where s.name='(name)' and s.dayActive='(day)'"
                .replace("(name)", eventTemp.getTitle())
                .replace("(day)", eventTemp.getStartDate() + ""));
    }

    public void onDateSelect(SelectEvent selectEvent) {
        Date date = (Date) selectEvent.getObject();
        clearValues();
        schedule.setDayActive(date);
    }
    
    public void logOut() {
        try {
            Faces.removeSessionAttribute(FacesUtil.ATTRIBUTE_USER);
            Faces.logout();
            Faces.invalidateSession();
            Faces.redirect("index.jsf");
        } catch (ServletException ex) {

        } catch (IOException ex) {

        }

    }
    /*
     public void onEventResize(ScheduleEntryResizeEvent event) {
     FacesUtil.addMessage("Resize", null, FacesMessage.SEVERITY_INFO);
     }
     */

    public void setScheduleService(IScheduleService scheduleService) {
        this.scheduleService = scheduleService;
    }

    public void paramNameImage(String imageName) {
        mothSelected = imageName;
    }

    public String getImage() {
        if (image == null) {
            selectImage();
        }
        return image;
    }

    public String getLinkShare() {
        return linkShare;
    }

    public void setLinkShare(String linkShare) {
        this.linkShare = linkShare;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Schedule getSchedule() {
        return schedule;
    }

    public void setSchedule(Schedule schedule) {
        this.schedule = schedule;
    }

    public void setSystemUserService(ISystemUserService systemUserService) {
        this.systemUserService = systemUserService;
    }

    public String uploadFile() throws IOException {
        image = null;
        String pathURL = FacesContext.getCurrentInstance().getExternalContext()
                .getRealPath("/");

        String compl = pathURL + capturePathMonth(mothSelected.split("-")[0]);
        compl = compl.replace("/", File.separator);

        //CREA EL NOMBRE DEL NUEVO ARCHIVO "MES-1.JPG"
        String temp = compl.substring(compl.lastIndexOf(File.separator));
        temp = temp.replace(".jpg", "").replace(File.separator, ""); //ENERO-1
        String anterior = temp;//ENERO-1
        String[] sep = temp.split("-");// sep[0]="ENERO"  sep[1]=1

        //ELIMINA EL ARCHIVO ANTERIOR
        for (int i = 0; i < getListMonth().size(); i++) {
            //String complx = pathURL + capturePathMonth(sep[0]);
            if (listMonth.get(i).startsWith(sep[0])) {
                try {
                    String complx = pathURL + "resources/images/" + listMonth.get(i);
                    File filrem = new File(complx);
                    filrem.deleteOnExit();
                    filrem.delete();
                } catch (Exception e) {
                }

            }
        }

        int addNumber = Integer.parseInt(sep[1]) + 1;// addNumber=2
        temp = temp.replace(sep[1], addNumber + ""); //temp=ENERO-2
        // Extract file name from content-disposition header of file part
        String fileName = getFileName(file);
        if (fileName.endsWith("jpg")) {
            String newFileName = compl.replace(anterior, temp);
            File outputFilePath = new File(newFileName);
            // Copy uploaded file to destination path
            InputStream inputStream = null;
            OutputStream outputStream = null;
            try {
                inputStream = file.getInputStream();
                outputStream = new FileOutputStream(outputFilePath);

                int read = 0;
                final byte[] bytes = new byte[1024];
                while ((read = inputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, read);
                }

                FacesUtil.addMessage("Subido con éxito", null, FacesMessage.SEVERITY_INFO);
            } catch (IOException e) {
                e.printStackTrace();

            } finally {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            }
        } else {
            FacesUtil.addMessage("Solo se aceptan JPG...", "No subio archivo", FacesMessage.SEVERITY_INFO);
        }
        file = null;
        listMonth = null;
        return null;    // return to same page
    }

    // Extract file name from content-disposition header of file part
    private String getFileName(Part part) {
        final String partHeader = part.getHeader("content-disposition");
        for (String content : part.getHeader("content-disposition").split(";")) {
            if (content.trim().startsWith("filename")) {
                return content.substring(content.indexOf('=') + 1).trim()
                        .replace("\"", "");
            }
        }
        return null;
    }

    private String capturePathMonth(String month) {
        String last = "";
        for (int i = 0; i < getListMonth().size(); i++) {
            String[] part = getListMonth().get(i).split("-");
            if (part[0].startsWith(month)) {
                last = "resources/images/" + getListMonth().get(i);
            }
        }
        return last;
    }

    private void selectImage() {
        Calendar cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH);

        if (month == Calendar.JANUARY) {
            image = capturePathMonth("ENERO");
        } else if (month == Calendar.FEBRUARY) {
            image = capturePathMonth("FEBRERO");
        } else if (month == Calendar.MARCH) {
            image = capturePathMonth("MARZO");
        } else if (month == Calendar.APRIL) {
            image = capturePathMonth("ARBIL");
        } else if (month == Calendar.MAY) {
            image = capturePathMonth("MAYO");
        } else if (month == Calendar.JUNE) {
            image = capturePathMonth("JUNIO");
        } else if (month == Calendar.JULY) {
            image = capturePathMonth("JULIO");
        } else if (month == Calendar.AUGUST) {
            image = capturePathMonth("AGOSTO");
        } else if (month == Calendar.SEPTEMBER) {
            image = capturePathMonth("SETIEMBRE");
        } else if (month == Calendar.OCTOBER) {
            image = capturePathMonth("OCTUBRE");
        } else if (month == Calendar.NOVEMBER) {
            image = capturePathMonth("NOVIEMBRE");
        } else if (month == Calendar.DECEMBER) {
            image = capturePathMonth("DICIEMBRE");
        }
    }

    public List<String> getListMonth() {
        if (listMonth == null) {
            String remov = FacesContext.getCurrentInstance().getExternalContext()
                    .getRealPath("/") + "resources/images/";
            listMonth = new ArrayList<>(Arrays.asList(new File(remov.replace("/", File.separator)).list()));

        }
        return listMonth;
    }

    public void setListMonth(List<String> listMonth) {
        this.listMonth = listMonth;
    }

    public Part getFile() {
        return file;
    }

    public void setFile(Part file) {
        this.file = file;
    }

    public String getMothSelected() {
        return mothSelected;
    }

    public void setMothSelected(String mothSelected) {
        this.mothSelected = mothSelected;
    }

    public TemplateDescription getTemplateDescription() {
        return templateDescription;
    }

    public void setTemplateDescription(TemplateDescription templateDescription) {
        this.templateDescription = templateDescription;
    }

    public List<TemplateDescription> getListTemplate() throws Exception {
        if (listTemplate == null) {
            listTemplate = templateDescriptionService.list();
        }
        return listTemplate;
    }

    public void setListTemplate(List<TemplateDescription> listTemplate) {
        this.listTemplate = listTemplate;
    }

    public void setTemplateDescriptionService(ITemplateDescriptionService templateDescriptionService) {
        this.templateDescriptionService = templateDescriptionService;
    }

    public Integer getHtmlDescriptId() {
        return htmlDescriptId;
    }

    public void setHtmlDescriptId(Integer htmlDescriptId) {
        this.htmlDescriptId = htmlDescriptId;
    }

}
